_package("caf.ui");

_import("caf.mui.Component");

/**
 * 地图组件
 */
_class("Map", Component, function(){
	var libload = false,
		ev = document.createEvent('HTMLEvents');
	ev.initEvent('mapReady',false,false);
	
	this._init = function(){
		_super._init.call(this);
		this._map = null;
		this._element = null;
		this._conf = null;
		this._control = {};									//地图控件
		this._markers = [];									//标记
		this._textMarkers = [];								//文字标注
		this._windows = [];									//信息窗
		this._gIndex = 0;
		this._mapImgUrl = 'http://stc.ditu.aliyun.com/stcMap?';
		//this._mapUrl = ['lib/map024.js','lib/ajax.js'];
		this._mapUrl = ['http://api.ditu.aliyun.com/map.js','http://api.ditu.aliyun.com/ajax.js'];
	};
	//加载js文件
	this.bind = function(obj,conf){
		this._conf = conf;
		this._element = obj;
		//绑定静态图片 无需加载外部库
		if(conf.type==='mapimg'){
			this.initImgMap();
		}
		//绑定地图 异步加载外部库后执行地图初始化
		else{
			if(!libload){  //避免重复加载
				runtime.loadScripts(this._mapUrl, this, function(){
					libload = true;
					this.init(obj);
				});
			}else{
				this.init(obj);
			}
		}
	};
	this.positionSuccess = function(l){
		lat = l.coords.latitude;
		lng = l.coords.longitude;
		this._map.centerAndZoom(new AliLatLng(lat,lng), zoom);
		this.mapAddon();
	};
	this.positionError = function(l){
		//获取失败 定位到杭州西湖
		this._map.centerAndZoom(new AliLatLng(lat,lng), zoom);
		this.mapAddon();
	};
	//初始化地图
	this.init = function(obj){
		_super.init.apply(this, arguments);
		var _this = this;
		lat = 30.238747;
		lng = 120.14532;
		zoom =  13;
		this._map = new AliMap(this._self);

		//初始化地图定位
		if(this._conf.center){
			var coords = this._conf.center.split(',');
			lat = coords[0];
			lng = coords[1];
			zoom = coords[2] || zoom;
			this._map.centerAndZoom(new AliLatLng(lat,lng), zoom);
			this.mapAddon();
		}else{
			//获取设备坐标
			CloudAPI.Utility.toast('获取当前位置中，请稍候');
			this.getCurrentPosition(this, this.positionSuccess, this.positionError);
		}
	};
	this.createApi = function(name, func){
		var k = "__caf_"  + name;
		window[k] = func;
		return k;
	};
	this.initImgMap = function(){
		var imgUrl = this.mapImg(this._conf.center,this._conf.size,this._conf.marker);
		this._map = document.createElement('img');
		this._map.src = imgUrl;
		this._element.appendChild(this._map);
	};
	this.mapAddon = function(){
		var i,l;
		//添加控件
		if(this._conf.control){
			var control = this._conf.control.split(',');
			l = control.length;
			for(i = 0; i < l; i++){
				this.addControl(control[i]);
			}
		}
		//添加工具
		if(this._conf.tool){
			var tool = this._conf.tool.split(',');
			l = tool.length;
			for(i = 0; i < l; i++){
				this.addTool(tool[i]);
			}
		}
		//添加标记
		if(this._conf.marker){
			var marker = this._conf.marker.replace(/\'/g,'"');
			marker = JSON.parse(marker);
			l = marker.length;
			for(i = 0; i < l; i++){
				this.addMarker(marker[i]);
			}
		}
		//添加周边搜索
		if(this._conf.localSearch){
			var search = this._conf.localSearch.replace(/\'/g,'"');
			search = JSON.parse(search);
			this.startLocalSearch(search);
		}
		//抛出地图加载完成事件
		this._element.dispatchEvent(ev);
	};
//基础方法
	/**
	 * 获取当前位置
	 * @param {Object} agent
	 * @param {Object|Function} func 获取成功回调函数
	 * @param {Object|Function} error 获取失败回调函数
	 */
	this.getCurrentPosition = function(agent, func, error){
		var cbid = runtime._task.add(agent, func);
		var fail = error;
		
		CloudAPI.Device.DeviceStateInfo.getCurrentPosition(
			this.createApi("pos_suc", function(position){
				runtime._task.send(cbid, position);
			}),
			this.createApi("pos_fail", function(msg){
				fail(msg);
				runtime._task.cancel(cbid);
				runtime.error(msg);
			})
		);
	};
	/**
	 * 定位中心和缩放级别
	 * @param {String} center 中心点纬度、经度、缩放级别（可选）
	 */
	this.setCenter = function(center){
		var coords = center.split(',');
		var _this = this;
		this.mapReady(function(){
			if(coords[2]){
				_this._map.centerAndZoom(new AliLatLng(coords[0],coords[1]), coords[2]);
			}else{
				_this._map.centerAndZoom(new AliLatLng(coords[0],coords[1]));
			}
		});		
	};
	/**
	 * 异步地图对象生成后执行
	 * @param {Function} callback 地图对象生成后执行的回调函数
	 */
	this.mapReady = function(callback){
		if(this._map){
			callback();
		}else{
			this.addListener(this._element,'mapReady',this,callback);
		}
	};
	/**
	 * 获取静态地图url地址
	 * @param {String} c 地图加载完成后执行的回调函数
	 * @param {String} s 地图加载完成后执行的回调函数
	 * @param {String} m 地图加载完成后执行的回调函数
	 */
	this.mapImg = function(c,s,m){
		return this._mapImgUrl + 'c=' + c + '&s=' + s + '&m=' + m;
	};

//基础方法结束
//线路显示
	this.directionPositionSuccess = function(l){
		this._direction.from = new AliLatLng(l.coords.latitude, l.coords.longitude);
		this._direction.points = [this._direction.from, this._direction.to];
		this._direction.execute();
	};
	this.directionPositionError = function(){
		CloudAPI.Utility.toast('无法获取当前位置。');
	};
	this.initDirection = function(){
		var _this = this;
		this._direction = new AliDirection();
		this._direction._lines = [];
		this._direction.completeListener = AliEvent.addListener(this._direction,"directioncomplete",function(){
			_this.completeDirection();
		});
		this._direction.exceptionListener = AliEvent.addListener(this._direction,"directionexception",function(){
			_this.exceptionDirection();
		});
	};
	/**
	 * @param {String} from 起始位置坐标，如省略从设备获取当前坐标
	 * @param {String} to 结束位置坐标
	 */
	this.startDirection = function(from, to){
		var arg = arguments;
		var _this = this;
		this.mapReady(function(){
			if(!_this._direction){
				_this.initDirection();
			}
			if(arg.length === 1){
				var t = arg[0].split(',');
				_this._direction.to = new AliLatLng(t[0],t[1]);
				CloudAPI.Utility.toast('获取当前位置中，请稍候');
				_this.getCurrentPosition(_this, _this.directionPositionSuccess, _this.directionPositionError);				
			}else{
				var f = arg[0].split(',');
				_this._direction.from = new AliLatLng(f[0],f[1]);
				var t = arg[1].split(',');
				_this._direction.to = new AliLatLng(t[0],t[1]);
				_this._direction.points = [_this._direction.from, _this._direction.to];
				_this._direction.execute();
			}
		});
	};
	this.completeDirection = function(){
		var steps = this._direction.steps;
		var l = steps.length;
		var i;
		//删除之前结果
		if(this._direction._lines.length){
			this.removeDirection();
		}
		//绘制线路
		for(i = 0; i < l; i++){
			var line = new AliPolyline(steps[i].getTrack())
			this._direction._lines.push(line);
			this._map.addOverlay(line);
		}
		CloudAPI.Utility.toast('距离：' + this._direction.distance/1000 + '公里。');
	};
	this.exceptionDirection = function(){
		CloudAPI.Utility.toast('线路显示失败。');
	};
	this.removeDirection = function(){
		var ll = this._direction._lines.length;
		for(i = 0; i < ll; i++){
			var line = this._direction._lines.pop();
			line.depose();
		}
	};
	this.disposeDirection = function(){
		var direction = this._direction;
		AliEvent.removeListener(direction.completeListener);
		AliEvent.removeListener(direction.exceptionListener);
		if(this._direction._lines.length){
			this.removeDirection();
		}
		direction = null;
	};
//线路显示结束
//周边搜索
	this.startLocalSearch = function(cfg){
		var _this = this;
		this.mapReady(function(){
			if(!_this._search){
				_this.initLocalSearch();
			}
			var search = _this._search;
			search.style = cfg.style || null;
			search.keyword = cfg.keyword;
			search.center = _this._map.getCenter();
			search.bounds = _this._map.getBounds();
			search.pageSize = cfg.size || 10;
			search.start = 0;
			search.execute();
			var t;
			search.moveListener = AliEvent.addListener(_this._map,"aftermove",function(){
				clearTimeout(t);
				t = setTimeout(function(){
					search.center = _this._map.getCenter();
					search.bounds = _this._map.getBounds();
					search.execute();
				},500);
			});			
		});
	};
	this.initLocalSearch = function(){
		var _this = this;
		this._search = new AliLocalSearch();
		this._search.markers = [];
		this._search.completeListener = AliEvent.addListener(this._search,"searchcomplete",function(){
			_this.completeLocalSearch();
		});
		this._search.exceptionListener = AliEvent.addListener(this._search,"searchexception",function(){
			_this.exceptionLocalSearch();
		});
	};
	this.completeLocalSearch = function(){
		var search = this._search;
		var i = 0;
		var l = search.points.length;

		if(search.markers.length){ //删除之前搜索结果
			this.removeLocalSearch();
		}
		for(i = 0; i < l; i++){
			var point = search.points[i];
			var marker = {
				coords : point.latlng,
				win : {'title':search.keyword,'content':point.name}
			};
			if(search.style){
				marker.style = search.style;
			}
			this.addMarker(marker);
			search.markers.push(this._markers.length-1); //保存下标
		}
	};
	this.exceptionLocalSearch = function(){
		CloudAPI.Utility.toast('周边搜索失败。');
	};
	this.removeLocalSearch = function(){
		var search = this._search;
		var ml = search.markers.length;
		for(i = 0; i < ml; i++){
			var index = search.markers[i];
			this._markers[index].depose();
		}
		search.markers = [];
	};
	this.disposeLocalSearch = function(){
		var search = this._search;
		var i = 0;
		var l = search.points.length;
		AliEvent.removeListener(search.moveListener);
		AliEvent.removeListener(search.completeListener);
		AliEvent.removeListener(search.exceptionListener);
		if(search.markers.length){ //删除搜索结果
			this.removeLocalSearch();
		}
		this._search = null;
	};
//周边搜索结束
/* 地址匹配
	/**
	 * @param {String} data 要转换的数据
	 * @param {Function} callback 回调函数
	 * @param {String} type 转换类型
	 */
	this.transGeo = function(data,callback,type){
		var url;
		if(type === 'coords' || typeof type === 'undefined'){						//没类型或者类型为coords，将地址转换成坐标
			url = 'http://gc.ditu.aliyun.com/geocoding?a=';
			data = encodeURIComponent(data) + '&b=';
		}else if(type === 'address'){											//类型为address，将坐标转换成地址
			url = 'http://10.249.194.52:8080/regeocoding?l=';
			data = data + '&type=111&b=';
		}else if(type === 'place'){											//类型为place，将坐标转换成行政区
			url = 'http://recode.ditu.aliyun.com/dist_query?l=';
			data = data + '&c=';
		}else{
			return;
		}
		this.mAjax(url,data,callback);
	};
	this.mAjax = function(url,data,callback){
		var callName = 'cb_' + this._gIndex;
		this._gIndex++;
		url = url + data + callName;
		window[callName] = AliEvent.getCallback(this,function(result){
			if(result){
				callback(result);
			}
			AliUtils.removeScript(url);
			window[callName]=null;
		});
		AliUtils.loadScript(url,"GBK");
	};
//地址匹配结束

//控件管理
	//添加控件
	this.addControl = function(name,pos){
		var _this = this;
		this.mapReady(function(){
			var i = false;
			if(name === 'zoom'){			//缩放
				_this._control.zoom = new AliMapLargeControl({hidePanBtn:true,hideZoomBtn:false,hideZoomBar:true});
			}else if(name === 'type'){		//地图类型
				_this._control.type = new AliMapTypeControl();
			}else if(name === 'scale'){		//比例尺
				_this._control.scale = new AliMapScaleControl(); 
				if(!pos){
					pos = {position:[40,-48]};
				}
			}else if(name === 'eagle'){		//鹰眼
				_this._control.eagle = new AliMapOverviewControl();
			}else{
				return;
			}
			_this._map.addControl(_this._control[name]);
			if(pos){
				_this.locateControl(name,pos);
			}
		});
	};
	//设置控件位置
	this.locateControl = function(name,pos){
		if(pos.layout){
			this._control[name].setLayout({x:pos.layout[0],y:pos.layout[1]});
		}
		if(pos.position){
			this._control[name].setPosition({x:pos.position[0],y:pos.position[1]});	
		}
	};
	//设置控件样式
	//this.setControlStyle = function(cfg){
	//};
	//删除控件
	this.removeControl = function(name){
		this._control[name].remove();		
	};
//控件管理结束

//地图标注
	//textMarker
	/**
	 * @param {Object} point 标记的坐标对象（AliLatLng）
	 * @param {Object} text 标记的信息
	 * @param {Object} target 所属的marker
	 */
	this.addtextMarker = function(point,text,target){
		var _this = this;
		var style = text.style || 'font-size:20px;color:#fff;';
		var textMarker = null;
		var offset = text.offset || {x:0,y:-45};
		this.mapReady(function(){
			textMarker = new AliPointOverlay(point,'<span style="'+style+'">'+text.content+'</span>',{offset:offset});
			_this._textMarkers.push(textMarker);
			_this._map.addOverlay(textMarker);

			if(target){ //如果该文字标记是某个标注的一部分，则将其保存在标记对象中，并在清除标记时一并清除
				target.text = textMarker;
				target.textListener = AliEvent.addListener(target,'remove',function(){
					AliEvent.removeListener(target.textListener);
					target.text = null;
					textMarker.depose();
				});	
			}
		});
	};
	//marker
	/**
	 * @param {Object} markerInfo 标记的信息
	 */
	this.addMarker = function(markerInfo){
		var _this = this;
		var marker = null;
		this.mapReady(function(){
			var point;
			if(typeof markerInfo.coords === 'string'){
				var coords = markerInfo.coords.split(',');
				point = new AliLatLng(coords[0],coords[1])
				marker = new AliMarker(point);
			}
			else if(markerInfo.coords.constructor === AliLatLng){
				point = markerInfo.coords;
				marker = new AliMarker(point);
			}
			_this._markers.push(marker);
			_this._map.addOverlay(marker);
			if(markerInfo.style){
				_this.modifyMarker(marker,markerInfo.style);
			}
			if(markerInfo.text){
				_this.addtextMarker(point,markerInfo.text,marker);
			}
			if(markerInfo.win){
				marker.clickListener = AliEvent.addListener(marker,'click',function(){
					marker.win = marker.openInfoWindow(markerInfo.win.title,markerInfo.win.content);
					marker.win.moveIntoView(20);			//将信息窗口移到可视范围内
					//_this._map.panTo(marker.getLatLng());  标记居中
				});
			}
		});
	};
	this.modifyMarker = function(target,style){
		target.setIcon(new AliIcon(style.url,style.size,style.anchor));
	};
	//infoWindow
	this.addInfoWindow = function(lat,lng,cfg,target){
		var win = new AliInfoWindow(new AliLatLng(lat,lng));
		this._windows.push(win);
		this._map.addOverlay(win);
		this.modifyInfoWindow(win,cfg);

		if(target){ //如果该信息框是某个标注的一部分，则将其保存在标记对象中，并在关闭该信息框时清除之
			target.win = win;
			target.winListener = AliEvent.addListener(win,'close',function(){
				AliEvent.removeListener(target.winListener);
				target.win = null;
			});	
		}
	};
	this.modifyInfoWindow = function(target,cfg){
		if(cfg.title){
			target.setTitle(cfg.title);	
		}
		if(cfg.content){
			target.setContent(cfg.content);
		}
		if(cfg.opacity){
			target.setOpacity(cfg.opacity);
		}
	};
//地图标注结束

//工具管理
	//工具添加
	this.addTool = function(target){
		if(target === 'distance'){
			this.initDistance();
		}else if(target ==='navigation'){
			this.initNavigation();
		}
	};
	//测距
	this.initDistance = function(){
		this._distanceLine = [];								//测距线
		this._distanceStat = false;								//测距状态
		this._distanceLineColor = ['blue','red','green'];		//测距线颜色
		this._distanceLineColorIndex = 0;						//测距线颜色索引

		this._distanceControl = this.createElement(this._self,'div','caf-map-distance-btn');
		this.addListener(this._distanceControl,"click",this,function(e){
			if(this._distanceStat){
				var target = this._distanceLine[this._distanceLine.length-1];
				this._distanceStat = false;
				this.removeDistance(target);
			}else{
				this.startDistance();
			}
		});
	};
	this.startDistance = function (){
		this._distanceStat = true;
		var line = new AliPolyline([]);
		var _this = this;
		this._distanceLine.push(line);
		line.point = [];
		line.stepIcon = [];

		//画线
		this._map.addOverlay(line);
		line.startDrawing();
		line.setLineColor(this._distanceLineColor[this._distanceLineColorIndex]);
		line.setLineWeight(6);
		this._distanceLineColorIndex = this._distanceLineColorIndex === 2 ? 0 : ++this._distanceLineColorIndex;

		//初始化提示信息
		CloudAPI.Utility.toast('点击地图可测量位置距离。');

		//绑定点击事件
		line.clickListener = AliEvent.addListener(_this._map,"click",function(point){
			_this.printDistance(line,point);
		});
		//绑定测距结束事件
		line.endListener = AliEvent.addListener(line,"drawend",function(){
			AliEvent.removeListener(line.clickListener);
			AliEvent.removeListener(line.endListener);
			if(_this._distanceStat){
				_this.endDistance(line);	
			}
		});
	};
	this.printDistance = function(target,point){
		var _this = this;
		var p = this._map.fromContainerPixelToLatLng(point);
		var stepIcon;
		target.point.push(p);

		if(target.point.length>1){
			var l = (AliLatLng.getDistance(target.point)/1000).toString()+ 'km';
			
			//修改提示信息
			CloudAPI.Utility.toast('总长：'+l);
			stepIcon = new AliPointOverlay(p,'<div class="caf-map-distance-stepicon" title="'+l+'"></div>');
		}else{
			stepIcon = new AliPointOverlay(p,'<div class="caf-map-distance-stepicon starticon" title="起点"></div>');
		}
		this._map.addOverlay(stepIcon);
		target.stepIcon.push(stepIcon);
	};
	this.endDistance = function(target){
		var lastPoint = target.point.pop();
		var _this = this;

		target.win = new AliInfoWindow(lastPoint);
		target.win.setContent((AliLatLng.getDistance(target.point)/1000).toString()+'km');
		target.win.setTitle('总距离');
		this._map.addOverlay(target.win);

		target.winListener = AliEvent.addListener(target.win,"close",function(){
			_this.removeDistance(target);
		});

		this._distanceStat = false;
	};
	this.removeDistance = function(target){
		var l = target.stepIcon.length;
		var i;
		for(i = 0; i < l; i++){
			target.stepIcon[i].depose();
		}
		target.depose();
		AliEvent.removeListener(target.winListener);
		target = null;
	};
	this.disposeDistance = function(){
		var l = this._distanceLine.length;
		var i;
		for(i = 0; i < l; i++){
			this._distanceLine[i].win.close();
		}
		this._distanceControl.parentNode.removeChild(this._distanceControl);
		this._distanceLine = null;
		this._distanceStat = null;
		this._distanceLineColor = null;
		this._distanceLineColorIndex = null;
	};
	//导航工具
	this.initNavigation = function(){
		var _this = this;
		var barHtml = '';
		this._navigation = null;								//导航对象
		this._navigationStat = false;							//导航工具打开状态

		this._navigationControl = this.createElement(this._self,'div','caf-map-navigation-icon');
		this._navigationForm = this.createElement(this._self,'div','caf-map-navigation-form');
		this._navigationFrom = this.createElement(this._navigationForm,'div','caf-map-navigation-from');
		this._navigationTo = this.createElement(this._navigationForm,'div','caf-map-navigation-from');
		this._navigationType = this.createDomElement(this._navigationForm,'<div class="caf-tabpanel" _tag="tag=a:tabpanel id=test-tabpanel act=3"><div class="caf-tabcontent" _tabname="自驾"></div><div class="caf-tabcontent" _tabname="公交"></div><div class="caf-tabcontent" _tabname="步行"></div></div>');
		this.hide(this._navigationForm,0,this,function(){});

		this.addListener(this._navigationControl,"click",this,function(e){
			this.show(_this._navigationForm,0,this,function(){});
		});
	};
	this.startNavigation = function(){
	};
	this.executeNavigation = function(){
	};
	this.disposeNavigation = function(){
	};
//工具管理结束

//静态地图结束
	this.dispose = function(){
		this._map = null;
		this._conf = null;
		this._control = null;
		this._mapUrl = null;
		this._mapReady = null;
		_super.dispose.apply(this);
	};
});